# -*- coding: utf-8 -*-
# @Time    : 2023/6/5 22:39
# @Author  : Z.J. Zhang
# @Email   : zijingzhang@mail.ustc.edu.cn
# @File    : _common.py
# @Software: PyCharm
import os.path

import matplotlib

matplotlib.use('tkagg')

import numpy
import shapely.geometry
import stl
from myPySldWrap import sw_tools

FREE_CAD_BIN_PATH = r'G:\Program Files\FreeCAD 0.19\bin'
import sys
from shapely.ops import unary_union
import matplotlib.pyplot as plt
from stl import mesh

sys.path.append(FREE_CAD_BIN_PATH)
import FreeCAD
_ = FreeCAD  # Do not auto format the import command
# TODO: 下面的两句import需在import FreeCAD之后
import Part
import Mesh

def _choose_2_axis(pt3ds: numpy.ndarray) -> numpy.ndarray:
    """
    :param pt3ds: shape (N, 3, 3)
    选择平面图的两轴
    :return: shape (N, 3, 3)
    """
    choosed_flag = [True] * 3

    for axis in range(3):
        # print(len(set((pt3ds[:, :, axis]).ravel())))
        if len(set((pt3ds[:, :, axis]).ravel())) == 1:
            choosed_flag[axis] = False
    return pt3ds[:, :, choosed_flag]




# _longest_words_not_longer_than_N(
#     """AREA FOCUSING_ELECTRODE   POLYGONAL -dZ_FOCUSING R_INPUT -dZ_FOCUSING R_SHELL 0,R_SHELL 0,+R_BEAM_TUNNEL-dr_focusing -dZ_FOCUSING2,+R_BEAM_TUNNEL-dr_focusing -dZ_FOCUSING,temp_r1 -dZ_FOCUSING R_INPUT;""",
#     30)
# auto_format(
#     """AREA FOCUSING_ELECTRODE   POLYGONAL -dZ_FOCUSING R_INPUT -dZ_FOCUSING R_SHELL 0,R_SHELL 0,+R_BEAM_TUNNEL-dr_focusing -dZ_FOCUSING2,+R_BEAM_TUNNEL-dr_focusing -dZ_FOCUSING,temp_r1 -dZ_FOCUSING R_INPUT;"""
#     )


def facets_to_area(facets: numpy.ndarray, ):
    """

    :param facets: shape (N, 3, 2)
    :return:
    """
    facet_polygons = [shapely.geometry.Polygon(facet) for facet in facets]
    return unary_union(facet_polygons)


def stl_solid_body_project_to_conformal_plane(mesh: stl.Mesh, axis_id_of_normal_vector: int):
    """
    将含有单个三维实体（solid body）的stl网格转化为在某个主平面的投影。
    主平面的法向量应为X/Y/Z之一，分别以0、1、2表示。
    :param mesh:
    :param axis_id_of_normal_vector:
    :return:
    """
    pts_3d = mesh.points.reshape((-1, 3, 3))
    choosed_flag = [True] * 3
    choosed_flag[axis_id_of_normal_vector] = False
    pts_2d = pts_3d[:, :, choosed_flag]  # 将三维坐标点“压平”到某一个投影平面，该投影平面的法向量应为X/Y/Z之一，分别以0、1、2表示。
    # TODO: 以下删除面积为0的小三角形是为了避免union成多个几何对象。
    #  若存在面积为0的三角形（三点共线时），unary_union的结果是多个Polygon。这应该是shapely库的bug。
    # plt.figure()

    not_delete_flag = [True] * len(pts_2d)
    i = 0
    for triangle in pts_2d:
        # plt.plot(*triangle.T)
        if shapely.geometry.Polygon(triangle).area == 0:
            not_delete_flag[i] = False
        i += 1
    return facets_to_area(pts_2d[not_delete_flag])


def sldprt_to_stl(sldprt_name: str,export_to_step= True):
    """
    将.sldprt文件转化为.stl文件
    :return: 转化后的stl文件路径
    """
    sw_tools.connect_sw('2020')
    # with   sw_tools.open_part(sldprt_name) as sldprt :
    prefix = os.path.splitext(sldprt_name)[0]
    stpname = prefix + '.step'
    if export_to_step:
        sw_tools.export_to_step(sldprt_name, dst=prefix)

    shape = Part.Shape()
    shape.read(stpname)
    mesh = Mesh.Mesh()
    mesh.addFacets(shape.tessellate(0.01))

    stlname = prefix + '.stl'
    mesh.write(stlname)

    # stp = r"D:\MagicFiles\HPM\12.5GHz\swANODE.STEP"  # 转化前step文件路径 abc是文件名
    # stl = r"D:\MagicFiles\HPM\12.5GHz\swANODE.stl"  # 转化后stl文件路径
    #
    # shape = Part.Shape()
    # shape.read(stp)
    # mesh = Mesh.Mesh()
    # mesh.addFacets(shape.tessellate(0.01))
    # mesh.write(stl)
    #
    # pass
    return stlname


if __name__ == '__main__':
    sldprt_to_stl(r"D:\MagicFiles\HPM\12.5GHz\swANODE.SLDPRT")
    plt.ion()
    polygons = stl_solid_body_project_to_conformal_plane(mesh.Mesh.from_file(r"D:\MagicFiles\HPM\12.5GHz\swANODE.STL"),
                                                         2)
    i = 0
    plt.figure()
    plt.plot(*polygons.boundary.xy, label='swANODE_%d' % i)
    # for polygon in polygons:
    #     plt.plot(*polygon.exterior.xy, label='swANODE_%d'%i)
    #     i+=1
    #
    #
    #
